#include "public.h"
#include "log.hpp"
#include <sys/epoll.h> 


using namespace std;

const int default_epoll_event_size = 1024;
const int default_buffer_size = 1024;

class Epoll {
public:
    Epoll(int size = default_epoll_event_size) :_event_size(size) {}

    ~Epoll() { 
        close(_epfd);
    }
    
    int epoll_crt() {
        _epfd = epoll_create(1);
        if (_epfd == -1) {
            lg(ERROR, "epoll_create err, err string: %s", strerror(errno));
            return -1;
        }
        lg(INFO, "epoll_create success, fd = %d", _epfd);
        return _epfd;
    }

    int epoll_wait(int timeout) {
        int nfds = ::epoll_wait(_epfd, _event, _event_size, timeout);
        if (nfds == -1) {
            lg(ERROR, "epoll_wait err, err string: %s", strerror(errno));
            return -1;
        }
        lg(INFO, "epoll_wait success, %d events ready", nfds);
        return nfds;
    }

    int epoll_ctl(int op, int target_fd, int flags = 0) {
        struct epoll_event event;
        event.events = flags;
        event.data.fd = target_fd;
        // 既然已经知道是哪个fd了，为什么还要设置到data中？
        // 方便在读取时得知是哪个fd就绪了
        int ret = ::epoll_ctl(_epfd, op, target_fd, &event);
        if(ret == -1) {
            lg(ERROR, "epoll_ctl err, err string: %s", strerror(errno));
            return -1;
        }
        lg(INFO, "epoll_ctl success");
        return ret;
    }
    
    int get_epfd() {
        return _epfd;
    }

    const struct epoll_event *get_ready_event_array() {
        return _event;
    }

private:
    int _epfd;
    struct epoll_event _event[default_epoll_event_size];
    int _event_size;
};